#ifndef FDB_H
#define FDB_H 1

#include <unistd.h>

/*
 * Constants.
 */

/*
 * Datatypes.
 */
typedef void column_t;
typedef void condition_t;
typedef void database_t;
typedef void maintenance_vacuum_t;
typedef void query_t;
typedef void result_t;
typedef void table_storage_t;
typedef void table_t;
typedef void transaction_t;

typedef int result_e;

typedef enum transaction_isolation_e {
	DIRTY_READ,
	READ_COMMITTED,
	REPEATABLE_READ,
	SERIALIZED,
} transaction_isolation_e;

typedef enum query_type_e {
	QUERY_SELECT,
	QUERY_INSERT,
	QUERY_DELETE,
	QUERY_UPDATE,
} query_type_e;
typedef int (*query_callback_f)(query_t *, void *ctx);

/*
 * Column definition functions.
 */
column_t *column_new(char *, const char *, ...);
column_t *column_new_list(char *, const char *, char **, int);
void column_destroy(column_t *);

/*
 * Table definition functions.
 */
table_t *table_new(char *);
void table_add_column(table_t *, column_t *);
int table_get_column_count(table_t *);
char *table_get_column_datatype(table_t *, int);
int table_get_column_datatype_args(table_t *, int , char ***, int *);
int table_get_column_id(table_t *, char *);
char *table_get_column_name(table_t *, int);
void table_destroy(table_t *);

condition_t *condition_callback_new(query_callback_f, void *);
condition_t *condition_predicate_new(int, char *, int, ...);
condition_t *condition_predicate_new_list(int, char *, int, size_t *, char **);
condition_t *condition_negate(condition_t *);
void condition_destroy(condition_t *);

int result_eod(result_e);
int result_error(result_e);
const char *result_text(result_e);
int result_ok(result_e);

database_t *database_open(const char *);
int database_table_create(database_t *, table_t *);
int database_table_drop(database_t *, const char *);
int database_table_open(database_t *, const char *, table_storage_t *);
table_t *database_table_get(database_t *, const char *);
void database_close(database_t *);

int maintenance_vacuum_database(transaction_t *);
int maintenance_vacuum_table(transaction_t *, const char *);

transaction_t *transaction_begin(database_t *, transaction_isolation_e);
int transaction_commit(transaction_t *);
int transaction_rollback(transaction_t *);

query_t *query_new(transaction_t *);
result_e query_data_get(query_t *, int, char **, size_t *);
result_e query_column_get_id(query_t *, char *, int *);
result_e query_datatype_args_get(query_t *, int, char ***, int *);
result_e query_datatype_get(query_t *, int, char **);
result_e query_execute(query_t *);
result_e query_finalize(query_t *);
result_e query_prepare(query_t *, query_type_e, const char *);
result_e query_step(query_t *);
void query_append_conditions(query_t *, ...);
void query_append_conditions_list(query_t *, int, condition_t **);
void query_data_set(query_t *,...);
void query_data_set_list(query_t *, char **, size_t *);
void query_destroy(query_t *);
void query_update_callback(query_t *, query_callback_f, void *);

#endif
